// =====================================================================
//
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//
// =====================================================================
#region

using System;
using System.ServiceModel.Description;
using SL.IdentityModel.Protocols.WSTrust;


#endregion

namespace Microsoft.Xrm.Sdk.Client
{
	public interface IServiceConfiguration<TService>
	{
		Uri ServiceUri { get; }

		/// <summary>
		/// 	Contains the STS IssuerEndpoints as determined dynamically by calls to AuthenticateCrossRealm.
		/// </summary>
		CrossRealmIssuerEndpointCollection CrossRealmIssuerEndpoints { get; }

		ServiceEndpointMetadata ServiceEndpointMetadata { get; }

		#region Authenticate

		/// <summary>
		/// 	Authenticates against the Trusted CRM Secure Token Service using client credentials supporting both
		/// 	Username and Windows (when in Federation mode) and returns a wrapper with both the RequestSecurityTokenResponse and the SecurityToken.
		/// 
		/// 	Will return null when in ActiveDirectory mode.
		/// </summary>
		/// <param name = "clientCredentials">A ClientCredentialsinstance with the Windows credentials or the UserName/Password</param>
		/// <returns>SecurityTokenResponse that contains both the RTSR and the SecurityToken</returns>
		void Authenticate(ClientCredentials clientCredentials);

		/// <summary>
		/// 	Authenticates against the Trusted CRM Secure Token Service using a Security Token retrieved from 
		/// 	an Identity Provider other than the Trusted CRM Secure Token Service (when in Federation mode) and 
		/// 	returns a wrapper with both the RequestSecurityTokenResponse and the SecurityToken.
		/// </summary>
		/// <param name = "securityTokenResponse">A Security Token Response obtained from an Identity Provider.</param>
		/// <returns>SecurityTokenResponse that contains both the RTSR and the SecurityToken</returns>
		void Authenticate(RequestSecurityTokenResponse securityTokenResponse);

		/// <summary>
		/// 	Authenticates against a remote Secure Token Service using client credentials supporting both
		/// 	Username and Windows (when in Federation mode) and returns a wrapper with both the RequestSecurityTokenResponse and the SecurityToken.
		/// 
		/// 	Will throw a NotSupportedException when in ActiveDirectory mode.
		/// </summary>
		/// <param name = "clientCredentials">A ClientCredentials instance with the Windows credentials or the UserName/Password</param>
		/// <param name = "appliesTo">The identifier of the STS to authenticate on behalf of</param>
		/// <param name = "crossRealmSts">The uri of the cross realm STS metadata endpoint</param>
		/// <returns>SecurityTokenResponse that contains both the RTSR and the SecurityToken</returns>
		void AuthenticateCrossRealm(ClientCredentials clientCredentials, String appliesTo, Uri crossRealmSts);

		/// <summary>
		/// 	Authenticates against a remote Secure Token Service using a Security Token retrieved from 
		/// 	an Identity Provider (when in Federation mode) and 
		/// 	returns a wrapper with both the RequestSecurityTokenResponse and the SecurityToken.
		/// 
		/// 	Will throw a NotSupportedException when in ActiveDirectory mode.
		/// </summary>
		/// <param name = "securityTokenResponse">A Security Token Response obtained from an Identity Provider.</param>
		/// ///
		/// <param name = "appliesTo">The identifier of the STS to authenticate on behalf of</param>
		/// <param name = "crossRealmSts">The uri of the cross realm STS metadata endpoint</param>
		/// <returns>SecurityTokenResponse that contains both the RTSR and the SecurityToken</returns>
		void AuthenticateCrossRealm(RequestSecurityTokenResponse securityTokenResponse, String appliesTo, Uri crossRealmSts);

		/// <summary>
		/// 	Authenticates against a remote Secure Token Service using client credentials supporting both
		/// 	Username and Windows (when in Federation mode) and returns a wrapper with both the RequestSecurityTokenResponse and the SecurityToken.
		/// 
		/// 	Will throw a NotSupportedException when in ActiveDirectory mode.
		/// </summary>
		/// <param name = "clientCredentials">A ClientCredentials instance with the Windows credentials or the UserName/Password</param>
		/// <param name = "deviceToken">The device token required by Live ID</param>
		/// <param name = "appliesTo">The identifier of the STS to authenticate on behalf of</param>
		/// <param name = "crossRealmSts">The uri of the cross realm STS metadata endpoint</param>
		/// <returns>SecurityTokenResponse that contains both the RTSR and the SecurityToken</returns>
		/// <summary>
		/// 	Authenticates a user against Windows Live ID.  The UserName.UserName and UserName.Password MUST be populated
		/// 	with the user name and password, and the SecurityToken must be set to a valid device security token.
		/// </summary>
		/// <param name = "clientCredentials">A ClintCredentials instance with the UserName.UserName and UserName.Password set.</param>
		/// <param name = "deviceSecurityToken">A Security Token response received from authenticating the user's device with Windows Live ID.</param>
		/// <returns>SecurityTokenResponse that contains both the RTSR and the SecurityToken</returns>
		void Authenticate(ClientCredentials clientCredentials, RequestSecurityTokenResponse deviceSecurityToken);

		/// <summary>
		/// 	Authenticates a registered device against Windows Live ID.  The UserName.UserName and UserName.Password MUST be populated
		/// 	with the device name and password.
		/// </summary>
		/// <param name = "clientCredentials">A ClintCredentials instance with the UserName.UserName and UserName.Password set.</param>
		/// <returns>SecurityTokenResponse that contains both the RTSR and the SecurityToken</returns>
		void AuthenticateDevice(ClientCredentials clientCredentials);

		event EventHandler<SignOnCompletedEventArgs> SignInComplete;
		event EventHandler<ServiceMetadataLoadedEventArgs> MetadataLoaded;
		event EventHandler<SignOnCompletedEventArgs> DeviceSignInComplete;
		event EventHandler<ServiceMetadataLoadedEventArgs> MetadataLoadFailure;
		event EventHandler<IdentityProvidersLoadCompletedEventArgs> IdentityProviderLoaded;
		#endregion Authenticate

		void GetIdentityProvider(String userPrincipalName);
		/// <summary>
		/// 	Contains the list of urls and binding information required in order to make a call to a WCF service.  If the service is configured
		/// 	for On-Premise use only, then the endpoint(s) contained within will NOT require the use of an Issuer Endpoint on the binding.
		/// 
		/// 	If the service is configured to use Claims (Federation,) then the binding on the service endpoint MUST be configured to use
		/// 	the appropriate Issuer Endpoint, i.e., UserNamePassword, Kerberos, etc.
		/// </summary>
		Microsoft.Xrm.Sdk.Client.ServiceEndpointMetadata.ServiceEndpointDictionary ServiceEndpoints { get; }
	}

	internal interface IWebAuthentication<TService>
	{
		void Authenticate(ClientCredentials clientCredentials, Uri uri, String keyType);
		void Authenticate(RequestSecurityTokenResponse securityToken, Uri uri, String keyType);
	}

	/// <summary>
	/// This interface does NOT provide support for LiveID based authentication.
	/// </summary>
	/// <typeparam name="TService"></typeparam>
	public interface IServiceManagement<TService>
	{
		/// <summary>
		/// 	This defaults to the first avaialble endpoint in the ServiceEndpoints dictionary if it has not been set.
		/// </summary>
		ServiceEndpoint CurrentServiceEndpoint { get; set; }

		/// <summary>
		/// 	Identifies whether the constructed service is using Claims (Federation) authentication or AD.
		/// </summary>
		AuthenticationProviderType AuthenticationType { get; }

		/// <summary>
		/// 	The following property contains the urls and binding information required to use a configured Secure Token Service (STS)
		/// 	for issuing a trusted token that the service endpoint will trust for authentication.
		/// 
		/// 	The available endpoints can vary, depending on how the administrator of the STS has configured the server, but may include 
		/// 	the following authentication methods:
		/// 
		/// 	1.  UserName and Password
		/// 	2.  Kerberos
		/// 	3.  Certificate
		/// 	4.  Asymmetric Token
		/// 	5.  Symmetric Token
		/// </summary>
		IssuerEndpointDictionary IssuerEndpoints { get; }

		/// <summary>
		/// 	Contains the STS IssuerEndpoints as determined dynamically by calls to AuthenticateCrossRealm.
		/// </summary>
		CrossRealmIssuerEndpointCollection CrossRealmIssuerEndpoints { get; }

		PolicyConfiguration PolicyConfiguration { get; }

		#region Authenticate

		/// <summary>
		/// 	
		/// </summary>
		/// <returns></returns>
		void Authenticate(AuthenticationCredentials authenticationCredentials);
		event EventHandler<AuthenticationCompletedEventArgs> AuthenticationComplete;

		#endregion Authenticate

	}
}
